package com.cskaoyan.shopping.service.impl;

import com.cskaoyan.mall.commons.exception.BaseBusinessException;
import com.cskaoyan.shopping.constants.ShoppingRetCode;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.entitys.ItemCat;
import com.cskaoyan.shopping.dal.entitys.StockItem;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dal.persistence.StockItemMapper;
import com.cskaoyan.shopping.dto.CartProductDto;
import com.cskaoyan.shopping.form.CartRequest;
import com.cskaoyan.shopping.form.CheckAllItemRequest;
import com.cskaoyan.shopping.service.ICartService;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author makabaka
 * @date 2022-12-02 20:12
 */

@Service
public class IShoppingCartsServiceImpl implements ICartService {


    @Autowired
    RedissonClient redissonClient;
    @Autowired
    CartItemConverter cartItemConverter;
    @Autowired
    ItemMapper itemMapper;
    @Autowired
    StockItemMapper stockItemMapper;

    /**
     * 实现获取购物车中商品列表
     * 在这里按照直接把商品表中的信息封装成的对象转换成购物车商品对象放入redis中实现
     * 因此直接取出即可
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<CartProductDto> getCartListById(Long userId) {
        RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
        Collection<CartProductDto> values = map.values();
        LinkedList<CartProductDto> cartProductDtos = new LinkedList<>();
        cartProductDtos.addAll(values);
        return cartProductDtos;
    }

    /**
     * 添加商品信息，先查找相关的表，然后把数据放入redis中，默认是选中状态
     *
     * @param request
     */
    @Override
    public void addToCart(CartRequest request) {
        RMap<Long, CartProductDto> map = redissonClient.getMap(request.getUserId().toString());
        // 先判断该商品是否已经存在
        CartProductDto oldCartProductDto = map.get(request.getProductId());
        Long num = Long.parseLong("0");
        if (oldCartProductDto != null && oldCartProductDto.getProductNum() != null && oldCartProductDto.getProductNum() > 0) {
            num = oldCartProductDto.getProductNum();
        }
        @NotNull Long productId = request.getProductId();
        // 先查找库存，库存为0或者商品库存不存在，则直接抛出异常
        StockItem stockItem = stockItemMapper.selectByPrimaryKey(productId);
        if (stockItem == null || stockItem.getStock_count() == 0) {
            throw new BaseBusinessException(ShoppingRetCode.ITEM_STOCK_IS_ZERO.getCode(),
                    ShoppingRetCode.ITEM_STOCK_IS_ZERO.getMessage());
        }
        Item item = itemMapper.selectByPrimaryKey(productId);
        if (item == null) {
            throw new BaseBusinessException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),
                    ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }
        // 把item表中的取出的库存数量替换掉
        num += request.getProductNum();
        item.setNum(stockItem.getStock_count().intValue());
        // 将item转换成cartProductDto对象
        CartProductDto cartProductDto = cartItemConverter.item2Dto(item);
        cartProductDto.setProductNum(num);
        cartProductDto.setChecked("true");
        map.put(productId, cartProductDto);
    }

    /**
     * 实现更新购物车数据的功能
     * 业务逻辑：1.根据uid从redis中获取数据 2.根据数量更新相关是数据即可
     *
     * @param request
     */
    @Override
    public void updateCartNum(CartRequest request) {
        RMap<Long, CartProductDto> map = redissonClient.getMap(request.getUserId().toString());
        CartProductDto cartProductDto = map.get(request.getProductId());
        cartProductDto.setChecked(request.getChecked());
        cartProductDto.setProductNum(request.getProductNum().longValue());
        map.put(request.getProductId(), cartProductDto);
        // addToCart(request);
    }

    /*
     * @Author makabaka
     * @Description //  [request]  全选购物车中的商品
     * @Date 9:08 2022/12/3
     * @Param [request]
     * @return
     **/
    @Override
    public void checkAllCartItem(CheckAllItemRequest request) {
        @NotNull Long userId = request.getUserId();
        RMap<Long, CartProductDto> userCarInfos = redissonClient.getMap(userId.toString());
        @NotNull String checked = request.getChecked();
        //将map转化为list
        List<CartProductDto> OldUserCarInfos = userCarInfos.values().stream().collect(Collectors.toList());
        for (CartProductDto oldUserCarInfo : OldUserCarInfos) {
            oldUserCarInfo.setChecked(checked);
            userCarInfos.put(oldUserCarInfo.getProductId(), oldUserCarInfo);
        }
    }


    /*
     * @Author makabaka
     * @Description //  删除一条购物车信息
     * @Date 20:13 2022/12/2
     * @Param
     * @return
     **/
    @Override
    public void deleteCartItem(Long uid, Long itemId) {
        RMap<Long, CartProductDto> map = redissonClient.getMap(uid.toString());
        map.remove(itemId);
    }


    /*
     * @Author makabaka
     * @Description //删除选中的商品
     * @Date 22:57 2022/12/2
     * @Param
     * @return
     **/

    @Override
    public void deleteCheckedItem(Long userId) {

        RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
        for (Long aLong : map.keySet()) {
            CartProductDto cartProductDto = map.get(aLong);
            if ("true".equals(cartProductDto.getChecked())) {
                map.remove(aLong);
            }
        }


    }
}
